# -*- coding: utf-8 -*-
"""
@Time ： 2021/8/11 21:40
@Auth ： Mr.掌心 2929184523
@Company ：特斯汀学院 @testingedu.com.cn
@Function ：接口测试关键字库
"""

import json
import traceback

import requests
from jsonpath import jsonpath

from common.Logger import logger


class Inter:
    """接口测试关键字类"""

    def __init__(self):
        self.session = requests.session()
        self.url = None
        self.text_result = ''
        self.json_result = {}
        # 关联的全局参数字典
        self.relations = {}

    def seturl(self, url: str = None):
        """
        设置url前缀
        :param url: url地址通用前缀
        """
        self.url = url
        return self.url

    def addheader(self, key: str = '', value: str = ''):
        """往session会话头里面添加一个键值对"""
        # 先关联
        value = self.__get_relations(value)
        self.session.headers[key] = value
        return self.session.headers

    def removeheader(self, key):
        try:
            self.session.headers.pop(key)
        except Exception as e:
            pass
        return self.session.headers

    def post(self, name: str = '', params: str = ''):
        """
        完成post请求发包
        :param name: 接口名字
        :param params: 参数
        """
        # 如果是绝对url地址，就不拼基础地址了
        if not name.startswith('http'):
            name = self.url + '/' + name

        # 关联
        params = self.__get_relations(params)

        # 字符串参数需要处理为字典
        params = self.__get_data(params)
        # # 如果你们传json字符串进来
        # if params.startswith('{'):
        #     params = json.loads(params)
        try:
            result = self.session.post(name, data=params)
            # # 如果需要编码处理
            # self.text_result = result.content.decode('utf8')
            self.text_result = result.text
            try:
                self.json_result = json.loads(self.text_result)
                return self.json_result
            except Exception as e:
                logger.debug('json处理异常')
                self.json_result = {"error": 'json处理异常'}
                return self.text_result

        except Exception as e:
            print('请求异常')
            # 让结果等于异常信息，主要方便排错
            self.text_result = str(traceback.format_exc())
            self.json_result = {"error": '请求异常'}
            return self.text_result

    def get(self, name: str = '', params: str = ''):
        """
        完成post请求发包
        :param name: 接口名字
        :param params: 参数
        """
        # 如果是绝对url地址，就不拼基础地址了
        if not name.startswith('http'):
            name = self.url + '/' + name

        # 关联
        params = self.__get_relations(params)

        # 字符串参数需要处理为字典
        params = self.__get_data(params)
        # # 如果你们传json字符串进来
        # if params.startswith('{'):
        #     params = json.loads(params)
        try:
            result = self.session.get(name, params=params)
            # # 如果需要编码处理
            # self.text_result = result.content.decode('utf8')
            self.text_result = result.text
            try:
                self.json_result = json.loads(self.text_result)
                return self.json_result
            except Exception as e:
                logger.debug('json处理异常')
                self.json_result = {"error": 'json处理异常'}
                return self.text_result

        except Exception as e:
            print('请求异常')
            # 让结果等于异常信息，主要方便排错
            self.text_result = str(traceback.format_exc())
            self.json_result = {"error": '请求异常'}
            return self.text_result

    def assertequals(self, result_key: str = '', expect_result: str = ''):
        """断言上一步请求中，json_result里面的result_key的值和expect_result相等"""
        # 获取实际结果
        try:
            actual_result = str(jsonpath(self.json_result, result_key)[0])
        except:
            actual_result = 'None'
        expect_result = self.__get_relations(expect_result)
        if actual_result == expect_result:
            return 1, actual_result
        else:
            return 0, actual_result

    def savejson(self, json_key: str, param_name: str):
        """把前一次请求结果里面的某个字段保存为全局参数"""
        try:
            json_value = str(jsonpath(self.json_result, json_key)[0])
        except:
            json_value = 'None'
        self.relations[param_name] = json_value
        return self.relations

    def __get_relations(self, params: str):
        if params:
            # 先从全局字典里面取关联
            for key in self.relations.keys():
                params = params.replace('{' + key + '}', self.relations.get(key))

            # 然后，从上一步的结果字典里面取关联
            for key in self.json_result.keys():
                params = params.replace('{' + key + '}', str(self.json_result.get(key)))

            return params
        else:
            return params

    def __get_data(self, params: str):
        """把url格式参数转换为字典"""
        if params:
            param_dict = {}
            params = params.split('&')
            for key_value in params:
                key = key_value[:key_value.find('=')]
                value = key_value[key_value.find('=') + 1:]
                param_dict[key] = value

            return param_dict
        else:
            return None
